<template>
  <div id="outerBox">
    <div id="senceList" v-if="editMode">
      <!-- <ul>
        <li
          v-for="(item, index) of senceList"
          :key="item.id"
          @click="selectSence(item)"
        >
          <span>{{ index + 1 }}</span>
          <div class="text">
            {{ item.text }}
          </div>
          <div class="close" @click="remove(item.id, $event)">
            <svg
              class="icon"
              style="
                width: 1em;
                height: 1em;
                vertical-align: middle;
                fill: currentColor;
                overflow: hidden;
              "
              viewBox="0 0 1024 1024"
              version="1.1"
              xmlns="http://www.w3.org/2000/svg"
              p-id="1315"
            >
              <path
                d="M544.448 499.2l284.576-284.576a32 32 0 0 0-45.248-45.248L499.2 453.952 214.624 169.376a32 32 0 0 0-45.248 45.248l284.576 284.576-284.576 284.576a32 32 0 0 0 45.248 45.248l284.576-284.576 284.576 284.576a31.904 31.904 0 0 0 45.248 0 32 32 0 0 0 0-45.248L544.448 499.2z"
                p-id="1316"
              ></path>
            </svg>
          </div>
        </li>
      </ul> -->

      <draggable
        v-model="senceList"
        group="people"
        @start="drag = true"
        @end="drag = false"
        item-key="id"
        id="senceListInnerBox"
      >
        <template #item="{ element, index }">
          <li
            @click="selectSence(element, index)"
            :style="{
              border: index + 1 == showIndex ? '1px solid #ff0000' : '',
            }"
          >
            <span>{{ index + 1 }}</span>
            <div class="text">
              <input
                type="text"
                v-model="element.text"
                @blur="txtChange(element)"
                @keypress.enter="txtChange(element)"
              />
              <!-- {{  }} -->
            </div>
            <div class="close" @click="remove(element.id, $event)">
              <svg
                class="icon"
                style="
                  width: 1em;
                  height: 1em;
                  vertical-align: middle;
                  fill: currentColor;
                  overflow: hidden;
                "
                viewBox="0 0 1024 1024"
                version="1.1"
                xmlns="http://www.w3.org/2000/svg"
                p-id="1315"
              >
                <path
                  d="M544.448 499.2l284.576-284.576a32 32 0 0 0-45.248-45.248L499.2 453.952 214.624 169.376a32 32 0 0 0-45.248 45.248l284.576 284.576-284.576 284.576a32 32 0 0 0 45.248 45.248l284.576-284.576 284.576 284.576a31.904 31.904 0 0 0 45.248 0 32 32 0 0 0 0-45.248L544.448 499.2z"
                  p-id="1316"
                ></path>
              </svg>
            </div>
          </li>
        </template>
      </draggable>

      <div id="icons">
        <input
          type="file"
          name=""
          style="display: none"
          id="fileJSON"
          accept=".json"
          @change="importJSON($event)"
        />
        <input
          type="file"
          name=""
          style="display: none"
          id="fileImg"
          accept="image/png"
          @change="importImg($event)"
        />

        <span @click="clickImg">
          <svg
            class="icon"
            style="
              width: 1em;
              height: 1em;
              vertical-align: middle;
              fill: currentColor;
              overflow: hidden;
            "
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="4010"
          >
            <path
              d="M553.1 509.1l-77.8 99.2-41.1-52.4c-3.2-4.1-9.4-4.1-12.6 0l-99.8 127.2c-4.1 5.2-0.4 12.9 6.3 12.9H696c6.7 0 10.4-7.7 6.3-12.9l-136.5-174c-3.3-4.1-9.5-4.1-12.7 0zM400 442m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0ZM854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326z m1.8 562H232V136h302v216c0 23.2 18.8 42 42 42h216v494z"
              p-id="4011"
            ></path>
          </svg>
        </span>

        <span @click="clickJSON">
          <svg
            class="icon"
            style="
              width: 1em;
              height: 1em;
              vertical-align: middle;
              fill: currentColor;
              overflow: hidden;
            "
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="3328"
          >
            <path
              d="M667.733333 864H170.666667c-6.4 0-10.666667-4.266667-10.666667-10.666667V170.666667c0-6.4 4.266667-10.666667 10.666667-10.666667h309.333333V320c0 40.533333 34.133333 74.666667 74.666667 74.666667h160v38.4c0 17.066667 14.933333 32 32 32s32-14.933333 32-32V298.666667c0-8.533333-4.266667-17.066667-8.533334-23.466667l-170.666666-170.666667c-6.4-6.4-14.933333-8.533333-23.466667-8.533333H170.666667C130.133333 96 96 130.133333 96 170.666667v682.666666c0 40.533333 34.133333 74.666667 74.666667 74.666667h497.066666c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32z m46.933334-550.4v17.066667H554.666667c-6.4 0-10.666667-4.266667-10.666667-10.666667V160h19.2l151.466667 153.6zM853.333333 597.333333H599.466667l51.2-51.2c12.8-12.8 12.8-32 0-44.8-12.8-12.8-32-12.8-44.8 0l-106.666667 106.666667c-12.8 12.8-12.8 32 0 44.8l106.666667 106.666667c6.4 6.4 14.933333 8.533333 23.466666 8.533333s17.066667-2.133333 23.466667-8.533333c12.8-12.8 12.8-32 0-44.8L599.466667 661.333333H853.333333c17.066667 0 32-14.933333 32-32S870.4 597.333333 853.333333 597.333333z"
              p-id="3329"
            ></path>
          </svg>
        </span>
        <span @click="exportJSON">
          <svg
            class="icon"
            style="
              width: 1em;
              height: 1em;
              vertical-align: middle;
              fill: currentColor;
              overflow: hidden;
            "
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="2659"
          >
            <path
              d="M582.4 864H170.666667c-6.4 0-10.666667-4.266667-10.666667-10.666667V170.666667c0-6.4 4.266667-10.666667 10.666667-10.666667h309.333333V320c0 40.533333 34.133333 74.666667 74.666667 74.666667h160v38.4c0 17.066667 14.933333 32 32 32s32-14.933333 32-32V298.666667c0-8.533333-4.266667-17.066667-8.533334-23.466667l-170.666666-170.666667c-6.4-6.4-14.933333-8.533333-23.466667-8.533333H170.666667C130.133333 96 96 130.133333 96 170.666667v682.666666c0 40.533333 34.133333 74.666667 74.666667 74.666667h411.733333c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32z m132.266667-550.4v17.066667H554.666667c-6.4 0-10.666667-4.266667-10.666667-10.666667V160h19.2l151.466667 153.6zM866.133333 669.866667l-106.666666-106.666667c-12.8-12.8-32-12.8-44.8 0s-12.8 32 0 44.8l51.2 51.2H512c-17.066667 0-32 14.933333-32 32S494.933333 725.333333 512 725.333333h253.866667l-51.2 51.2c-12.8 12.8-12.8 32 0 44.8 6.4 6.4 14.933333 8.533333 23.466666 8.533334s17.066667-2.133333 23.466667-8.533334l106.666667-106.666666c8.533333-10.666667 8.533333-32-2.133334-44.8z"
              p-id="2660"
            ></path>
          </svg>
        </span>
      </div>
    </div>
    <div id="map"></div>
    <div id="nextBtn" v-if="editMode">
      <span
        class="iconfont icon-jietu"
        @click="log"
        :style="{ color: drawActive ? '#1890ff' : '' }"
      ></span>
      <span class="iconfont icon-next" @click="next"></span>
      <!-- <span class="iconfont icon-editor" @click="setEdit"></span> -->
      <span class="iconfont icon-play" @click="play"></span>
    </div>
  </div>
</template>

<script setup lang="ts">
import Tile from "ol/layer/Tile";
import Map from "ol/Map";
import View, { FitOptions } from "ol/View";
import OSM from "ol/source/OSM";
import ImageLayer from "ol/layer/Image";
import Static from "ol/source/ImageStatic";
import Vector from "ol/source/Vector";
import Draw from "ol/interaction/Draw";
import GeometryType from "ol/geom/GeometryType";

import { Geometry, Polygon, SimpleGeometry } from "ol/geom";
import { Coordinate } from "ol/coordinate";
import VectorLayer from "ol/layer/Vector";
import Feature from "ol/Feature";
import Style from "ol/style/Style";
import Text from "ol/style/Text";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";

import { onMounted, ref } from "vue";
import { Extent } from "ol/extent";
import WKT from "ol/format/WKT";
import draggable from "vuedraggable";

let drag = ref(false);

let map: Map;
let drawSource: Vector = new Vector();
const drawLayer = new VectorLayer({
  source: drawSource,
});
const selectLayer = new VectorLayer({
  source: new Vector(),
});

const imageLayer = new ImageLayer();
const imageExtent = [0, 0, 31300, 19140];
const editMode = ref(true);
const fitOption: FitOptions = { duration: 800, padding: [50, 50, 50, 50] };
interface sence {
  id: number;
  text: string;
  extent: Extent;
  geom: string;
}

let senceList = ref<sence[]>([]);
const selectSence = ({ id, extent, geom }: sence, index: number) => {
  const feature: any = drawSource.getFeatureById(id)?.clone();
  feature.setId(id);
  let style: Style = new Style({
    stroke: new Stroke({
      color: "#ff0000",
      width: 2,
    }),
  });
  feature?.setStyle(style);
  selectLayer.getSource()?.clear();
  selectLayer.getSource()?.addFeature(feature);
  map.getView().fit(extent, fitOption);
  showIndex.value = index + 1;
};

const remove = (id: number, evt: Event) => {
  evt.stopPropagation();
  const feature: Feature | any = drawSource.getFeatureById(id);
  drawSource.removeFeature(feature);
  const sF = selectLayer.getSource()?.getFeatureById(id);
  if (sF) {
    selectLayer.getSource()?.clear();
  }

  const index = senceList.value.findIndex((i) => i.id == id);
  senceList.value.splice(index, 1);
};

const initMap = () => {
  map = new Map({
    target: "map",
    view: new View(),
    layers: [imageLayer, drawLayer, selectLayer],
    controls: [],
    // interactions: [draw],
  });

  imageLayer.setSource(
    new Static({
      url: "./123.png",
      imageExtent,
    })
  );

  map.addInteraction(draw);
  map.getView().fit(imageExtent, { padding: [50, 50, 50, 50] });
  draw.setActive(false);
  map.on("click", (evt) => {
    if (!editMode.value) {
      next();
    } else {
      selectLayer.getSource()?.clear();
    }
  });
};
let index = 0;
let showIndex = ref(0);
const next = () => {
  if (showIndex.value == senceList.value.length) {
    map.getView().fit(imageExtent, { duration: 0, padding: [50, 50, 50, 50] });
    showIndex.value = 0;
    setEdit();
    return;
  }

  const geom = senceList.value[showIndex.value].extent;
  map.getView().fit(geom, fitOption);
  showIndex.value++;
};

const draw = new Draw({
  type: GeometryType.CIRCLE,
  geometryFunction: (coordinates, geometry) => {
    var start: any = coordinates[0];
    var end: any = coordinates[1];
    if (!geometry) {
      geometry = new Polygon([
        [start, [start[0], end[1]], end, [end[0], start[1]], start],
      ]);
    }
    geometry.setCoordinates([
      [start, [start[0], end[1]], end, [end[0], start[1]], start],
    ]);
    return geometry;
  },
});

const drawStyle = new Style({
  fill: new Fill({ color: "#ffff0045" }),
  stroke: new Stroke({
    width: 1,
    color: "#1980ff",
  }),
});

draw.on("drawend", (evt) => {
  const feature = evt.feature;
  const id = ++index,
    text = id.toString();
  const style = drawStyle.clone();
  style.setText(
    new Text({
      text,
    })
  );
  feature.setId(id);
  feature.setStyle(style);

  drawSource.addFeature(feature);
  const geom: any = feature.getGeometry();
  const extent: Extent | any = geom?.getExtent();
  senceList.value.push({
    id,
    text,
    extent,
    geom: new WKT().writeGeometry(geom),
  });
  //   draw.setActive(false);
});

let drawActive = ref<boolean>(false);

const log = () => {
  drawActive.value = !draw.getActive();
  draw.setActive(!draw.getActive());
};

const txtChange = ({ id, text }: sence) => {
  const feature = drawSource.getFeatureById(id);
  const style = drawStyle.clone();

  style.setText(new Text({ text: [text, "bold 15px sans-serif"] }));
  feature?.setStyle(style);
};

const play = () => {
  showIndex.value = 0;
  map.updateSize();
  map.render();
  editMode.value = false;
  drawLayer.setVisible(false);
  selectLayer.setVisible(false);
  document.documentElement.requestFullscreen();
  draw.setActive(false);
};

const setEdit = () => {
  editMode.value = true;
  drawLayer.setVisible(true);
  document.exitFullscreen();
  selectLayer.setVisible(true);
};

const clickJSON = () => {
  document.getElementById("fileJSON")?.click();
};

const clickImg = () => {
  document.getElementById("fileImg")?.click();
};

const sc = (txt: any) => {
  senceList.value = [];
  for (let item of JSON.parse(txt) as sence[]) {
    senceList.value.push(item);
    const { id, text, geom } = item;
    const feature = new Feature();
    feature.setGeometry(new WKT().readGeometry(geom));
    const style = drawStyle.clone();
    style.setText(
      new Text({
        text,
      })
    );
    feature.setId(id);
    feature.setStyle(style);

    drawSource.addFeature(feature);
  }
};

const importJSON = (evt: Event) => {
  var file = (evt.target as any).files[0];
  //   filename = file.name.split(".")[0];
  var reader = new FileReader();
  reader.onload = function () {
    sc(this.result); //这里的 this 指向 FileReader
  };
  reader.readAsText(file);
};

const importImg = (evt: Event) => {
  var file = (evt.target as any).files[0];
  const thisSrc = URL.createObjectURL(file); //当前对象的地址
  const image = new Image();
  image.src = thisSrc;
  image.onload = () => {
    imageExtent[2] = image.width * 10;
    imageExtent[3] = image.height * 10;
    imageLayer.setSource(
      new Static({
        url: thisSrc,
        imageExtent,
      })
    );
    map.getView().fit(imageExtent);
  };
};

const exportJSON = () => {
  let element = document.createElement("a");
  element.setAttribute(
    "href",
    "data:text/plain;charset=utf-8," +
      encodeURIComponent(JSON.stringify(senceList.value))
  );

  element.setAttribute("download", new Date().getTime() + ".json");
  element.click();
};

onMounted(initMap);
</script>

<style scoped lang="less">
#outerBox {
  display: flex;
}

#map {
  height: 100vh;
  flex-grow: 1;
}
#nextBtn {
  position: absolute;
  top: 30px;
  right: 30px;
  span {
    font-size: 24px;
    margin: 0 10px;
    cursor: pointer;
  }
}
#senceList {
  width: 200px;
  height: 100vh;
  border: 1px solid #e2e2e2;
  box-sizing: border-box;

  #senceListInnerBox {
    padding: 10px 0px 10px 20px;
    overflow-y: scroll;
    height: calc(100% - 60px);
  }
  li {
    text-align: center;
    border: 1px solid #e2e2e2;
    margin-bottom: 10px;
    height: 50px;

    list-style-type: none;
    position: relative;
    span {
      width: 32px;
      position: absolute;
      left: -30px;
      text-align: center;
      font-size: 14px;
      color: #818181;
    }
    div.text {
      line-height: 50px;
      input {
        width: 120px;
        border: none;
        outline: none;
      }
    }
    div.close {
      position: absolute;
      right: 2px;
      top: -2px;
    }
  }
  #icons {
    text-align: center;
    span {
      margin: 0 10px;
      font-size: 25px;
      cursor: pointer;
    }
  }
}
</style>